1 Star 13 Fork 4

JanKinCai / jppe-rs

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

jppe-rs

Crates.io Crates.io License

这是一个基于Rust实现的字节流结构化序列化/反序列化通用库,可以应用于网络数据包解析、网络数据包组包、网络通信、文件内容解析等,觉得不错的小伙伴们请点个赞👍~

安装

Cargo.toml

[dependencies]
jppe = { version="1.0.0", features = ["derive"] }

Or

[dependencies]
jppe = { version="1.0.0", features = ["derive", "serde"] }

简单例子


use jppe::{ByteEncode, ByteDecode};


#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
pub struct SimpleExample {
    pub length: u16,
    // 这里是指定动态长度,也可以指定固定数值,比如:`#[jppe(length=3)]`
    // 还可以不指定`length`, 指定`byte_count=<1|2|4|8>`表示提前取走几个字节根据字节序转为长度数值
    #[jppe(length="length")]
    pub value: String,
    pub cmd: u8,
    // 这里指定了branch, 表示根据cmd的值进行枚举类型(enum)模式匹配, 同样也可以指定`byte_count`修饰符
    #[jppe(branch="cmd")]
    pub body: SimpleExampleBody,
}


#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode)]
#[repr(u8)]
pub enum SimpleExampleBody {
    Read {
        address: u8,
    } = 1,                    // 这里表示当前面的`cmd`字段为1,则会进入该分支解析
    Write {
        address: u8,
        value: [u8; 3],
    },                        // 这里如果不指定,默认是递增的关系为2
    #[jppe(enum_default)]
    Unknown,                  // 这里由于指定了默认分支,所以会被映射为`_ => { ... }`, 如果没有指定,Unknown序号为3,其他则会返回解析错误
}


fn main() {
    let input = b"\x00\x03\x31\x32\x33\x01\x05";
    let (input_remain, value) = jppe::decode::<SimpleExample>(input).unwrap();
    assert_eq!(value, SimpleExample { length: 3, value: "123".to_string(), cmd: 1, body: SimpleExampleBody::Read { address: 5 } });
    assert_eq!(input_remain.is_empty(), true);
    assert_eq!(jppe::encode(value), input);
}

默认值例子

[dependencies]
jppe = { version="1.0.0", features = ["derive", "jdefault"] }

use jppe::{ByteEncode, ByteDecode, Jdefault};

// 如果值长度小于0xff, 则可以不用指定byte_count=1, 否则需要指定byte_count=<2|4|8>, 表示多少个字节表示后续数据长度或者其他情况。

#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode, Jdefault)]
pub struct SimpleExample {
    #[jppe(byte_count=1, default="\"123\".to_string()")]
    pub value: String,
    #[jppe(byte_count=1)]
    pub body: SimpleExampleBody,
}


#[derive(Debug, PartialEq, Eq, ByteEncode, ByteDecode, Jdefault)]
#[repr(u8)]
pub enum SimpleExampleBody {
    Read {
        address: u8,
    } = 1,
    Write {
        address: u8,
        value: [u8; 3],
    },
    #[jppe(branch_default)]
    Unknown {
        #[jppe(default=10)]
        value: u8,
    },
}


fn main() {
    let value = SimpleExample::default();
    assert_eq!(value, SimpleExample {
        value: "123".to_string(),
        body: SimpleExampleBody::Unknown { value: 10 },
    });

    assert_eq!(jppe::encode(value), b"\x03\x31\x32\x33\x03\x0a");

    let (input_remain, value) = jppe::decode::<SimpleExample>(b"\x03\x31\x32\x33\x03\x0a").unwrap();
    assert_eq!(value, SimpleExample {
        value: "123".to_string(),
        body: SimpleExampleBody::Unknown { value: 10 },
    });
    assert_eq!(input_remain.is_empty(), true);
}

其他例子

常见功能

ContainerAttrModifiers

主要用于修饰某个struct/enum全局定义,表示struct/enum里面的字段都遵循,也可以通过FieldAttrModifiers修饰单个内容。

通用修饰符

  • byteorder=<"BE"|"LE">: 这是struct/enum类型全局字节序,BE(大端字节序)/LE(小端字节序), eg: #[jppe(byteorder="LE")].
  • encode_with: 自定义encode函数, eg: with_encode_example.
  • decode_with: 自定义decode函数, eg: with_decode_example.
  • with: 自定义encode/decode函数, eg: with_encode_example.
  • get_variable_name: 获取缓存变量, 必须配合variable_name使用,可以用于不用struct或enum类型传递, eg: variable_name_example.

枚举分支修饰符

  • branch_enum

FieldAttrModifiers

主要用于修饰struct/enum里面某个字段内容

  • byteorder=<"BE"|"LE">: 这是struct/enum类型局部字段字节序,BE(大端字节序)/LE(小端字节序), eg: #[jppe(byteorder="LE")]
  • length=<num|variable>: 数据长度, 支持int/&str/String/&[u8]类型, eg: length_example.
  • offset=<num|variable>: 字节流偏移,表示跳过几个字节.
  • count==<num|variable>: 数据条目数量, 支持Vec/HashMap类型.
  • full=<int>: 主要用于encode填充值, 默认为0, 常常用于offset偏移之后进行encode编码填充.
  • untake: 表示解析内容, 但是不取走字节, 后面的解析任然可以读取该字节.
  • linend|end_with=<string|bytes>: 指定结束位置, 支持String/&str/&[u8]/HashMap等类型.
  • key|starts_with: 指定精准匹配关键字, 必须配合linend使用, 支持string/&str/&[u8]等类型.
  • split: 指定分隔符, 常常用于Key: Value这种内容, 支持HashMap类型, eg: split_example
  • if_expr <bool expr>: 指定if表达式, 支持Option<T>类型, eg: if_expr_example.
  • encode_with: 自定义encode函数, eg: with_example.
  • decode_with: 自定义decode函数, eg: with_example.
  • with: 自定义encode/decode函数, eg: with_example.
  • with_args: 自定义encode/decode函数参数, eg: with_args_example.
  • encode_value: value处理表达式, eg: #[jppe(encode_value="length * 2")].
  • decode_value: value处理表达式, eg: #[jppe(decode_value="length / 2")].
  • variable_name: 指定整型类型缓存变量, eg: variable_name_example.
  • byte_count=<1|2|4|8>: 指定byte_count字节数量, 会取走对应字节映射数字, 常常用于下面类型:
    • String/&str/&[u8]: 提前取n个字节映射长度, eg: byte_count.
    • HexString/HexBytes: 提前取n个字节映射长度, eg: byte_count.
    • Enum: 提前取n个字节映射枚举索引, eg: enum_byte_count.
    • Vec<T>
  • skip: 数据类型需要实现Defaulttrait.
  • skip_encode: 跳过encode函数.
  • skip_decode: 数据类型需要实现Defaulttrait.
  • check_value:主要用于检查结果是否正常, 异常会返回错误
  • default: eg: default example

enum branch

数据类型

  • u8/u16/u32/u64/usize/u128
  • i8/i16/i32/i64/isize/i128
  • bool
  • f32/f64
  • String and &str
  • array[T; N]
  • Tuple
  • Vec<T>
  • &[u8]
  • Option<T>
  • Struct
  • Enum
  • PhantomData
  • HashMap: 支持String/&str/&[u8]类型, 可以指定#[jppe(count=xxx)]修饰符表示解析数量, 默认是50, eg: hashmap_example.
  • HashSet<T>: 需要指定#[jppe(count=xxx)]修饰符表示解析数量, 仅仅支持decode函数, 默认count=0, eg: hashset_example.
  • MacAddress: 内部实现MacAddress类型, eg: mac_example.
  • std::net::Ipv4Addr: Ipv4类型.
  • std::net::Ipv6Addr: Ipv6类型.
  • std::net::IpAddr: 必须指定length=<16|4>修饰符, 否则返回错误, eg: ip_address_example.
  • PpeAddress: 内部实现PpeAddress类型, 包含IPv4/IPv6/Mac/Usize地址类型, 必须指定length=<16|4|6|usize>修饰符, 否则返回错误, eg: ppe_address_example.
  • HexString: 内部实现HexString类型, eg: hex_example
  • HexBytes: 内部实现HexBytes类型, HexBytes引用类型, eg: hex_bytes_example
  • DateTime
  • Bit

TODO

  • jnet-rs: 基于jppe实现常见网络协议结构化定义.
  • jget-rs: 通过修饰符暴露pub fn get_xxxx(&self) -> xxxx函数,避免手动定义.
  • jdefault-rs:通过修饰符设置默认值, 可以集合jppe结构化定义实现默认值编码功能.
  • jfmt-rs: 主要用于格式化jppe定义结构化内容数据.
Copyright (c) 2023, jankincai Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

这是一个基于Rust实现的字节流结构化序列化/反序列化通用库,可以应用于网络数据包解析、网络数据包组包、网络通信、文件内容解析等 展开 收起
Rust
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Rust
1
https://gitee.com/JanKinCai/jppe-rs.git
git@gitee.com:JanKinCai/jppe-rs.git
JanKinCai
jppe-rs
jppe-rs
master

搜索帮助